home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-07-15 | 25.6 KB | 807 lines | [TEXT/MPS ] |
- //----------------------------------------------------------------------------------------
- // UVolumeBasedApp.cp
- // ETO20 MacApp 3.3.1, MPW 3.4.1
- // Copyright ©1996 Conrad Kopala
- // Twist Down Lists version 2.0a0 7/15/96
- //----------------------------------------------------------------------------------------
-
- #ifndef __UVOLUMEBASEDAPP__
- #include "UVolumeBasedApp.h"
- #endif
-
- //needs gTwistDownApp for FailNIL(aDocument = gTwistDownApp -> DoMakeVolumeDocument(kindOfDocCmd, volumeOwnedByDoc));
- #ifndef __UTWISTDOWNAPP__
- #include "UTwistDownApp.h"
- #endif
-
- //needs errNotHFSVolume, msgNotHFSVolume
- #ifndef __UTWISTDOWNGLOBALS__
- #include "UTwistDownGlobals.h"
- #endif
-
- // MacApp
-
- #ifndef __ULIST__
- #include "UList.h"
- #endif
-
- //ToolBox stuff
- //None
-
- //ANSI stuff
- //None
- //========================================================================================
- // CLASS MVolumeBasedApp
- //========================================================================================
- #undef Inherited
-
-
- #pragma segment MAInit
- MA_DEFINE_CLASS_M0(MVolumeBasedApp);
-
- //----------------------------------------------------------------------------------------
- // MVolumeBasedApp::MVolumeBasedApp
- //----------------------------------------------------------------------------------------
- #pragma segment MAInit
- MVolumeBasedApp::MVolumeBasedApp()
- {
- #if qDebug
- if (gPrintAppClassInfo)
- {
- fprintf(stderr, " Construct MVolumeBasedApp"); //Cannot use PrintAppConstructorClassInfo()
- //because MVolumeBasedApp does not descend
- //from TObject.
- fprintf(stderr, "\n");
- }
- #endif
- }
- //----------------------------------------------------------------------------------------
- // MVolumeBasedApp destructor
- //----------------------------------------------------------------------------------------
- #pragma segment MADestructorRes
- MVolumeBasedApp::~MVolumeBasedApp()
- {
- #if qDebug
- if (gPrintAppClassInfo)
- {
- fprintf(stderr, " Destruct MVolumeBasedApp"); //Cannot use PrintAppDestructorClassInfo()
- //because MVolumeBasedApp does not descend
- //from TObject.
- fprintf(stderr, "\n");
- }
- #endif
- }
- //----------------------------------------------------------------------------------------
- // MVolumeBasedApp::DoMakeVolume analog of DoMakeFile
- //----------------------------------------------------------------------------------------
- #pragma segment AOpen
- TVolume* MVolumeBasedApp::DoMakeVolume()
- {
- return NewVolume(gApplication -> fCreator);
- }
- //----------------------------------------------------------------------------------------
- // MVolumeBasedApp::ChooseVolume: analog of ChooseDocument new version
- //----------------------------------------------------------------------------------------
- #pragma segment AOpen
- Boolean MVolumeBasedApp::ChooseVolume(CommandNumber itsCommandNumber, TList** aVolumeList)
- {
-
- typedef SFTypeList* SFTypeListPtr;
- typedef SFTypeListPtr* SFTypeListHandle;
-
-
- MAVolatileInit(TVolume*, aVolume, NULL);
- Boolean volumeChosen;
-
- #if !qPowerPC && !qModelCFM
- if (HasCustomFile())
- {
- #endif
- ProcPtr fileFilter;
- TypeListHandle typeList;
- short dlgID;
- CPoint where;
- ProcPtr dlgHook;
- ProcPtr modalFilter;
- Ptr activeList;
- ProcPtr activateProc;
- StandardFileReply customReply;
- void* yourDataPtr = NULL;
-
- gApplication -> GetStandardFileParameters(itsCommandNumber, fileFilter, typeList, dlgID, where,
- dlgHook, modalFilter, activeList, activateProc,
- &customReply, yourDataPtr);
-
- SFTypeListPtr pTypeList;
- short numTypes = (short)(GetHandleSize((Handle)typeList) / sizeof(ResType));
- if (numTypes == 0)
- {
- numTypes = -1; // Tell Std File to display all types.
- pTypeList = (SFTypeListPtr) & pTypeList;// arbitrary, as long as it points to 4 bytes of valid memory
- }
- else
- {
- LockHandleHigh((Handle)typeList); // in case Std File does allocations
- pTypeList = *((SFTypeListHandle)typeList);
- }
-
- // Causes TApplication::GetEvent to call CheckRsrcUsage.
- gRsrcCheck = 0;
-
- FailInfo fi;
- Try(fi)
- {
-
- aVolume = this -> DoMakeVolume();
- volumeChosen = FALSE;
-
- FailOSErr(gApplication->InteractWithUser(gNotificationPtr, TAppleEvent::fgIdleProc));
-
- if (yourDataPtr == NULL)
- yourDataPtr = &itsCommandNumber;
-
- gClipboardMgr->AboutToLoseControl(TRUE); // so scrap gets converted
-
- FileFilterYDUPP cgfFileFilter = NewFileFilterYDProc(fileFilter);
- DlgHookYDUPP cgfDlgHook = NewDlgHookYDProc(dlgHook);
- ModalFilterYDUPP cgfModalFilter = NewModalFilterYDProc(modalFilter);
- ActivateYDUPP cgfActivateProc = NewActivateYDProc(activateProc);
-
- CustomGetFile(cgfFileFilter, numTypes, (*pTypeList), &customReply, dlgID, where, cgfDlgHook, cgfModalFilter, (short*)activeList, cgfActivateProc, yourDataPtr);
-
- cgfFileFilter = (FileFilterYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfFileFilter);
- cgfDlgHook = (DlgHookYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfDlgHook);
- cgfModalFilter = (ModalFilterYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfModalFilter);
- cgfActivateProc = (ActivateYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfActivateProc);
-
- gClipboardMgr->RegainControl(TRUE); // so scrap gets converted
-
- volumeChosen = customReply.sfGood;
- if (volumeChosen)
- {
- aVolume -> SpecifyWithStandardFileReply(customReply);
-
- if (!(aVolume -> IsHFSVolume()))
- {
- CStr31 volumeName;
- aVolume -> GetName(volumeName);
- gErrorParm3 = volumeName;
- Failure(errNotHFSVolume, msgNotHFSVolume);
- }
- }
-
- fi.Success();
- }
- else // Recover
- {
- typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
- aVolume = (TVolume *)FreeIfObject(aVolume);
- fi.ReSignal();
- }
-
- typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
-
-
-
- #if !qPowerPC && !qModelCFM
- // the following block of code is the "else" block for the above Gestalt check -
- // as with that check, it is only relevant if we are not built for PowerPC
- }
- else
- {
- ProcPtr fileFilter;
- TypeListHandle typeList;
- short dlgID;
- CPoint where;
- ProcPtr dlgHook;
- ProcPtr modalFilter;
- Ptr activeList;
- ProcPtr activateProc;
- SFReply reply;
- void* yourDataPtr = NULL;
-
- // We can't pass reply because it's a lowly SFReply, not a StandardFileReply
- gApplication -> GetStandardFileParameters(itsCommandNumber, fileFilter, typeList, dlgID, where,
- dlgHook, modalFilter, activeList, activateProc,
- NULL, yourDataPtr);
-
- SFTypeListPtr pTypeList;
- short numTypes = (short)(GetHandleSize((Handle)typeList) / sizeof(ResType));
- if (numTypes == 0)
- {
- numTypes = -1; // Tell Std File to display all types.
- pTypeList = (SFTypeListPtr) & pTypeList;// arbitrary, as long as it points to 4 bytes of valid memory
- }
- else
- {
- LockHandleHigh((Handle)typeList); // in case Std File does allocations
- pTypeList = *((SFTypeListHandle)typeList);
- }
-
- // Causes TApplication::GetEvent to call CheckRsrcUsage.
- gRsrcCheck = 0;
-
- FailInfo fi;
- Try(fi)
- {
-
- aVolume = this -> DoMakeVolume();
- volumeChosen = FALSE;
-
- FailOSErr(gApplication->InteractWithUser(gNotificationPtr, TAppleEvent::fgIdleProc));
-
- if (yourDataPtr == NULL)
- yourDataPtr = &itsCommandNumber;
-
- // We will pass the address of the CallBack instead of the modalFilter to
- // SFPGetFile It will add yourDataPtr parameter before passing on to the
- // ModalFilterProc supplied by SFPutParms this lets us assume a single calling
- // convention for that function.
-
- // Don't create a CallBack when the SF callback is NULL.
- // Also, pass itsCommandNumber as a default yourDataPtr.
-
- CallBack myFileFilterCallBack;
- SetCallBack(fileFilter, (long)yourDataPtr, &myFileFilterCallBack);
- FileFilterProcPtr aFileFilterProcPtr = fileFilter ? (FileFilterProcPtr)&myFileFilterCallBack : NULL;
-
- CallBack myModalHookCallBack;
- SetCallBack(dlgHook, (long)yourDataPtr, &myModalHookCallBack);
- DlgHookProcPtr aDlgHookProcPtr = dlgHook ? (DlgHookProcPtr)&myModalHookCallBack : NULL;
-
- CallBack myModalFilterCallBack;
- SetCallBack(modalFilter, (long)yourDataPtr, &myModalFilterCallBack);
- ModalFilterProcPtr aModalFilterProcPtr = modalFilter ? (ModalFilterProcPtr)&myModalFilterCallBack : NULL;
-
- gClipboardMgr->AboutToLoseControl(TRUE); // so scrap gets converted
-
- SFPGetFile(where, gEmptyString, aFileFilterProcPtr, numTypes, (*pTypeList), aDlgHookProcPtr, &reply, dlgID, aModalFilterProcPtr);
-
- gClipboardMgr->RegainControl(TRUE); // so scrap gets converted
-
- volumeChosen = reply.good;
-
- if (volumeChosen)
- {
- FailOSErr(aVolume -> SpecifyWithSFReply(reply));
-
- if (!(aVolume -> IsHFSVolume()))
- {
- CStr31 volumeName;
- aVolume -> GetName(volumeName);
- gErrorParm3 = volumeName;
- Failure(errNotHFSVolume, msgNotHFSVolume);
- }
- }
-
- fi.Success();
- }
- else // Recover
- {
- typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
- aVolume = (TVolume *)FreeIfObject(aVolume);
- fi.ReSignal();
- }
-
- typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
-
- }
- #endif
-
- if (volumeChosen)
- {
- MAVolatileInit(TList**, volatileVolumeList, aVolumeList);
-
- FailInfo fi;
- Try(fi)
- {
- // Return the file(s) chosen
- *volatileVolumeList = NewList();
- (*volatileVolumeList)->InsertLast(aVolume);
- fi.Success();
- }
- else
- {
- if (*volatileVolumeList)
- *volatileVolumeList = (TList*)FreeIfObject(*volatileVolumeList);
- aVolume = (TVolume*)FreeIfObject(aVolume);
- fi.ReSignal();
- }
- }
- else // user cancelled or something
- aVolume = (TVolume *)(FreeIfObject(aVolume)); // free the unwanted file object
-
- return volumeChosen;
- }
-
- //----------------------------------------------------------------------------------------
- // MVolumeBasedApp::ChooseVolume alternate old version
- //----------------------------------------------------------------------------------------
- #pragma segment AOpen
- Boolean MVolumeBasedApp::ChooseVolume(CommandNumber itsCommandNumber, TVolume** aVolume)
- {
-
- typedef SFTypeList* SFTypeListPtr;
- typedef SFTypeListPtr* SFTypeListHandle;
-
-
- MAVolatileInit(TVolume*, aNewVolume, NULL);
- Boolean volumeChosen;
-
- #if !qPowerPC && !qModelCFM
- if (HasCustomFile())
- {
- #endif
- ProcPtr fileFilter;
- TypeListHandle typeList;
- short dlgID;
- CPoint where;
- ProcPtr dlgHook;
- ProcPtr modalFilter;
- Ptr activeList;
- ProcPtr activateProc;
- StandardFileReply customReply;
- void* yourDataPtr = NULL;
-
- gApplication -> GetStandardFileParameters(itsCommandNumber, fileFilter, typeList, dlgID, where,
- dlgHook, modalFilter, activeList, activateProc,
- &customReply, yourDataPtr);
-
- SFTypeListPtr pTypeList;
- short numTypes = (short)(GetHandleSize((Handle)typeList) / sizeof(ResType));
- if (numTypes == 0)
- {
- numTypes = -1; // Tell Std File to display all types.
- pTypeList = (SFTypeListPtr) & pTypeList;// arbitrary, as long as it points to 4 bytes of valid memory
- }
- else
- {
- LockHandleHigh((Handle)typeList); // in case Std File does allocations
- pTypeList = *((SFTypeListHandle)typeList);
- }
-
- // Causes TApplication::GetEvent to call CheckRsrcUsage.
- gRsrcCheck = 0;
-
- FailInfo fi;
- Try(fi)
- {
-
- aNewVolume = this -> DoMakeVolume();
- volumeChosen = FALSE;
-
- FailOSErr(gApplication->InteractWithUser(gNotificationPtr, TAppleEvent::fgIdleProc));
-
- if (yourDataPtr == NULL)
- yourDataPtr = &itsCommandNumber;
-
- gClipboardMgr->AboutToLoseControl(TRUE); // so scrap gets converted
-
- FileFilterYDUPP cgfFileFilter = NewFileFilterYDProc(fileFilter);
- DlgHookYDUPP cgfDlgHook = NewDlgHookYDProc(dlgHook);
- ModalFilterYDUPP cgfModalFilter = NewModalFilterYDProc(modalFilter);
- ActivateYDUPP cgfActivateProc = NewActivateYDProc(activateProc);
-
- CustomGetFile(cgfFileFilter, numTypes, (*pTypeList), &customReply, dlgID, where, cgfDlgHook, cgfModalFilter, (short*)activeList, cgfActivateProc, yourDataPtr);
-
- cgfFileFilter = (FileFilterYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfFileFilter);
- cgfDlgHook = (DlgHookYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfDlgHook);
- cgfModalFilter = (ModalFilterYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfModalFilter);
- cgfActivateProc = (ActivateYDUPP)DisposeIfRoutineDescriptor((UniversalProcPtr)cgfActivateProc);
-
- gClipboardMgr->RegainControl(TRUE); // so scrap gets converted
-
- volumeChosen = customReply.sfGood;
- if (volumeChosen)
- {
- aNewVolume -> SpecifyWithStandardFileReply(customReply);
-
- if (!(aNewVolume -> IsHFSVolume()))
- {
- CStr31 volumeName;
- aNewVolume -> GetName(volumeName);
- gErrorParm3 = volumeName;
- Failure(errNotHFSVolume, msgNotHFSVolume);
- }
- }
-
- fi.Success();
- }
- else // Recover
- {
- typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
- aNewVolume = (TVolume *)FreeIfObject(aNewVolume);
- fi.ReSignal();
- }
-
- typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
-
-
-
- #if !qPowerPC && !qModelCFM
- // the following block of code is the "else" block for the above Gestalt check -
- // as with that check, it is only relevant if we are not built for PowerPC
- }
- else
- {
- ProcPtr fileFilter;
- TypeListHandle typeList;
- short dlgID;
- CPoint where;
- ProcPtr dlgHook;
- ProcPtr modalFilter;
- Ptr activeList;
- ProcPtr activateProc;
- SFReply reply;
- void* yourDataPtr = NULL;
-
- // We can't pass reply because it's a lowly SFReply, not a StandardFileReply
- gApplication -> GetStandardFileParameters(itsCommandNumber, fileFilter, typeList, dlgID, where,
- dlgHook, modalFilter, activeList, activateProc,
- NULL, yourDataPtr);
-
- SFTypeListPtr pTypeList;
- short numTypes = (short)(GetHandleSize((Handle)typeList) / sizeof(ResType));
- if (numTypes == 0)
- {
- numTypes = -1; // Tell Std File to display all types.
- pTypeList = (SFTypeListPtr) & pTypeList;// arbitrary, as long as it points to 4 bytes of valid memory
- }
- else
- {
- LockHandleHigh((Handle)typeList); // in case Std File does allocations
- pTypeList = *((SFTypeListHandle)typeList);
- }
-
- // Causes TApplication::GetEvent to call CheckRsrcUsage.
- gRsrcCheck = 0;
-
- FailInfo fi;
- Try(fi)
- {
-
- aNewVolume = this -> DoMakeVolume();
- volumeChosen = FALSE;
-
- FailOSErr(gApplication->InteractWithUser(gNotificationPtr, TAppleEvent::fgIdleProc));
-
- if (yourDataPtr == NULL)
- yourDataPtr = &itsCommandNumber;
-
- // We will pass the address of the CallBack instead of the modalFilter to
- // SFPGetFile It will add yourDataPtr parameter before passing on to the
- // ModalFilterProc supplied by SFPutParms this lets us assume a single calling
- // convention for that function.
-
- // Don't create a CallBack when the SF callback is NULL.
- // Also, pass itsCommandNumber as a default yourDataPtr.
-
- CallBack myFileFilterCallBack;
- SetCallBack(fileFilter, (long)yourDataPtr, &myFileFilterCallBack);
- FileFilterProcPtr aFileFilterProcPtr = fileFilter ? (FileFilterProcPtr)&myFileFilterCallBack : NULL;
-
- CallBack myModalHookCallBack;
- SetCallBack(dlgHook, (long)yourDataPtr, &myModalHookCallBack);
- DlgHookProcPtr aDlgHookProcPtr = dlgHook ? (DlgHookProcPtr)&myModalHookCallBack : NULL;
-
- CallBack myModalFilterCallBack;
- SetCallBack(modalFilter, (long)yourDataPtr, &myModalFilterCallBack);
- ModalFilterProcPtr aModalFilterProcPtr = modalFilter ? (ModalFilterProcPtr)&myModalFilterCallBack : NULL;
-
- gClipboardMgr->AboutToLoseControl(TRUE); // so scrap gets converted
-
- SFPGetFile(where, gEmptyString, aFileFilterProcPtr, numTypes, (*pTypeList), aDlgHookProcPtr, &reply, dlgID, aModalFilterProcPtr);
-
- gClipboardMgr->RegainControl(TRUE); // so scrap gets converted
-
- volumeChosen = reply.good;
-
- if (volumeChosen)
- {
- FailOSErr(aNewVolume -> SpecifyWithSFReply(reply));
-
- if (!(aNewVolume -> IsHFSVolume()))
- {
- CStr31 volumeName;
- aNewVolume -> GetName(volumeName);
- gErrorParm3 = volumeName;
- Failure(errNotHFSVolume, msgNotHFSVolume);
- }
- }
-
- fi.Success();
- }
- else // Recover
- {
- typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
- aNewVolume = (TVolume *)FreeIfObject(aNewVolume);
- fi.ReSignal();
- }
-
- typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
-
- }
- #endif
-
- if (volumeChosen)
- {
- MAVolatileInit(TVolume**, volatileVolume, aVolume);
-
- FailInfo fi;
- Try(fi)
- {
- // Return the volume chosen
- *volatileVolume = aNewVolume;
- fi.Success();
- }
- else
- {
- if (*volatileVolume)
- *volatileVolume = (TVolume*)FreeIfObject(*volatileVolume);
- aNewVolume = (TVolume*)FreeIfObject(aNewVolume);
- fi.ReSignal();
- }
- }
- else // user cancelled or something
- aNewVolume = (TVolume*)(FreeIfObject(aNewVolume)); // free the unwanted volume object
-
- return volumeChosen;
- }
- //----------------------------------------------------------------------------------------
- // MVolumeBasedApp::CanOpenVolume: analog of CanOpenDocument
- //----------------------------------------------------------------------------------------
- #pragma segment MAFinder
- // This is called only when opening/printing from the finder and from standard file;
- // it simulates the filtering done by Std File.
-
- Boolean MVolumeBasedApp::CanOpenVolume(CommandNumber itsCommandNumber, TVolume* aVolume)
- {
- Boolean returnValue = FALSE;
-
- ProcPtr fileFilter;
- TypeListHandle typeList = NULL;
- short dlgID;
- CPoint where;
- ProcPtr dlgHook;
- ProcPtr modalFilter;
- Ptr activeList;
- ProcPtr activateProc;
- void* yourDataPtr = NULL;
-
- gApplication -> GetStandardFileParameters(itsCommandNumber, fileFilter, typeList, dlgID, where,
- dlgHook, modalFilter, activeList, activateProc,
- NULL, yourDataPtr);
-
- CStr31 volumeName;
- aVolume -> GetName(volumeName);
-
- CInfoPBRec paramBlock;
-
- short numTypes = (short)(GetHandleSize((Handle)typeList) / sizeof(ResType));
- if (numTypes == 0)
- {
- if (!fileFilter)
- returnValue = TRUE; // no file filter then want all types
- else if (aVolume -> GetCatInfo(paramBlock) == noErr)
- {
- paramBlock.hFileInfo.ioNamePtr = (StringPtr)volumeName;
- // Call through the supplied filterProc
- returnValue = !((FileFilterYDProcPtr)fileFilter)(¶mBlock, NULL);
- }
- else
- returnValue = FALSE;
- }
- else
- {
- for (short i = 0; i < numTypes; ++i)
- {
- if (((long)(aVolume->fFileType)) == ((long)(*typeList)[i]))
- {
- if (!fileFilter)
- returnValue = TRUE;
- else if (aVolume -> GetCatInfo(paramBlock) == noErr)
- {
- paramBlock.hFileInfo.ioNamePtr = (StringPtr)volumeName;
- // Call through the supplied filterProc
- returnValue = !((FileFilterYDProcPtr)fileFilter)(¶mBlock, NULL);
- }
- else
- returnValue = FALSE;
- break;
- }
- }
- }
-
- typeList = (TypeListHandle)DisposeIfHandle((Handle)typeList);
- return returnValue;
- }
- //----------------------------------------------------------------------------------------
- // MVolumeBasedApp::OpenVolume: analog of OpenOld new version
- //----------------------------------------------------------------------------------------
- #pragma segment AOpen
- TDocument* MVolumeBasedApp::OpenVolume(CommandNumber itsOpenCommand, TList* aVolumeList)
- {
- MAVolatileInit(TDocument*, aDocument, NULL);
- MAVolatileInit(TVolume*, aVolume, NULL);
- MAVolatileInit(TVolume*, aNewVolume, NULL);
- MAVolatileInit(OSErr, savedError, 0);
- MAVolatileInit(long, savedMessage, 0);
-
- Size oldCodeReserve; // can't be volatile because it is passed by reference
- Size oldMemReserve; // can't be volatile because it is passed by reference
-
- {
- // Put iterator in a separate block so that it will go out of scope before the end of the method.
- // We don't want the iterator's failure handler to be invoked, because its stack ptr is munged.
- // If an error occurs, we'll just save it and ReSignal it after the iterator is gone.
-
- CObjectIterator iter(aVolumeList);
- for (aVolume = (TVolume *)iter.FirstObject(); iter.More() && !savedError; aVolume = (TVolume *)iter.NextObject())
- {
- CommandNumber kindOfDocCmd = itsOpenCommand;
- // reset aDocument and aNewVolume so that they no longer refer to items from the
- // last go round (important in case we fail downstream)…
- aDocument = NULL;
- aNewVolume = NULL;
-
- CStr31 volumeName;
- aVolume -> GetName(volumeName); // If failure occurs the file may already be
- // freed so we will save the name just in
- // case.
-
- aVolumeList -> Delete(aVolume); // ReadStationery if successful will dispose
- // of the file for us so if failure occurs
- // this had better not be in the file list.
-
- FailInfo fi;
- Try(fi)
- {
- // Set reserve down a little to ensure that we can open existing documents
- GetReserveSize(oldCodeReserve, oldMemReserve);
- SetReserveSize(oldCodeReserve, oldMemReserve / 2);
-
- TDocument * otherDoc = NULL; //For testing purposes, I find it useful to set otherDoc = NULL
- //which allows the same volume to be opened as many times
- //as needed to stress memory and induce failure. For a
- //shipping application, you don't want the user to be able
- //to open the same volume again and again so comment out the
- //following if statement which, of course, allows the same volume
- //to be opened more than once if fAllowUnlimitedDocs is TRUE.
-
- if (!gTwistDownApp -> fAllowUnlimitedDocs)
- otherDoc = gTwistDownApp -> FindDocument(aVolume);
-
- if (otherDoc)
- {
- otherDoc -> OpenAgain(kindOfDocCmd, aDocument);
- aVolume = (TVolume*)FreeIfObject(aVolume);
- SetReserveSize(oldCodeReserve, oldMemReserve);
- }
- else if (this -> CanOpenVolume(kindOfDocCmd, aVolume))
- {
- if (!(aVolume -> IsHFSVolume()))
- {
- gErrorParm3 = volumeName;
- Failure(errNotHFSVolume, msgNotHFSVolume);
- }
-
- TVolume* volumeOwnedByDoc = aVolume;
- aVolume = NULL;
-
- FailNIL(aDocument = gTwistDownApp -> DoMakeDocument(kindOfDocCmd, volumeOwnedByDoc));
-
- aDocument -> ReadDocument(kForDisplay);
-
- aDocument -> DoMakeViews(kForDisplay);
-
-
-
- FailSpaceIsLow(); // Fail if the document leaves us with no
- // memory
-
- // Set the reserve back to where it was
- SetReserveSize(oldCodeReserve, oldMemReserve);
-
- // Don't attempt to show the windows until we're sure we won't fail
- aDocument -> DoPostMakeViews(kForDisplay);
- }
- else
- Failure(errNotMyType, 0);
- fi.Success();
- }
- else // Recover
- {
- if (fi.message == 0 || fi.message == msgTooManyRows)
- gErrorParm3 = volumeName;
-
- // We may have ended up without a document because of a failure during document
- // init. b/c this can be the case we don't know what happened to aVolume, whether
- // it was freed by the document in the failure process or orphaned. Because of
- // this we will not free aVolume here.
- if (aDocument)
- //aDocument = (TDocument *)(FreeIfObject(aDocument)); // The document will free the file
- aDocument -> CloseAndFree(); //Use CloseAndFree because it removes the TWindow
- //associated with fTwistDownView from the windows
- //list if necessary. This window must be removed
- //from the list before it is freed. If it isn't
- //the program will crash the machine with an
- //access fault.
-
- aNewVolume = (TVolume*)FreeIfObject(aNewVolume); // If we successfully read the
- // stationery then aNewVolume will
- // be NULL
-
- // Set the reserve back to where it was
- SetReserveSize(oldCodeReserve, oldMemReserve);
-
- // Don't want to fail here, because the CObjectIterator (with its embedded FailInfo) is
- // still in scope. Instead, save the error info until after the iterator has self-destructed.
- // FailNewMessage(fi.error, fi.message, messageOpenFailed);
- savedError = fi.error;
- savedMessage = fi.message;
- if (!savedMessage)
- savedMessage = messageOpenFailed;
- }
- }
- } // iterator will self-destruct now
-
- if (savedError != noErr) // Do we need to ReSignal a failure?
- {
- // signal the failure
- Failure(savedError, savedMessage);
- }
-
- return aDocument;
- }
- //----------------------------------------------------------------------------------------
- // MVolumeBasedApp::OpenVolume: alternate old version
- //----------------------------------------------------------------------------------------
- #pragma segment AOpen
- TDocument* MVolumeBasedApp::OpenVolume(CommandNumber itsOpenCommand, TVolume* volumeOwnedByDoc)
- {
-
- MAVolatileInit(TDocument*, aDocument, NULL);
-
- FailInfo fi;
- Try(fi)
- {
-
- CommandNumber kindOfDocCmd = itsOpenCommand;
-
- FailNIL(aDocument = gTwistDownApp -> DoMakeDocument(kindOfDocCmd, volumeOwnedByDoc));
-
- aDocument -> ReadDocument(kForDisplay);
- FailSpaceIsLow(); // Fail if document leaves us with no room In UMemory
-
- aDocument -> DoMakeViews(kForDisplay);
- FailSpaceIsLow(); // Fail if document leaves us with no room In UMemory
-
- // Don't attempt to show the windows until we're sure we won't fail
- aDocument -> DoPostMakeViews(kForDisplay);
-
- fi.Success();
- }
- else // Recover
- {
- if (aDocument)
- {
- //aDocument = (TDocument *)(FreeIfObject(aDocument));
- aDocument -> CloseAndFree(); //Use CloseAndFree because it removes the TWindow
- //associated with fTwistDownView from the windows
- //list if necessary. This window must be removed
- //from the list before it is freed. If it isn't
- //the program will crash the machine with an
- //access fault.
- aDocument = NULL;
- }
-
- FailNewMessage(fi.error, fi.message, messageNewFailed);
- fi.ReSignal();
- }
-
-
- return aDocument;
-
- }
-
- #pragma segment Inline